---------------------------------------------------------------
-- @Copyright：           zour
-- @Description：         ngx启动与每次请求的调用入口函数

-- @modify time           2021-10-14
---------------------------------------------------------------

require "modules.business_advert.advert_define"
local gg = require "modules.business_advert.advert_gg"
local advert_common = require "modules.business_advert.advert_common"
local func_cmds       = require "modules.business_advert.advert_cmds_enter"
local func_acts       = require "modules.business_advert.advert_acts_enter"
local ns_auth_checker = require "modules.business_advert.advert_auth_checker"
local advert_config_get = require "modules.business_advert.advert_config_get"
local biz_utils = require "modules.business_common.business_utils"


local FOO = {
	_VERSION = '0.12.1',
	worker_id = ngx.worker.id(),
};

--===================================init function=====================================
--每分钟执行的定时器
local function timer_check()
	--每天更新一次 
	if uu.now()==advert_common.get_day_zero(uu.now()) then 
		func_cmds.timer_work()
	end
end

--worker启动时马上执行的函数，一般用来加载配置文件等
FOO.init_worker_by_lua_file = function()
	log.day_list(ADVERT, "info::business_advert init_worker_by_lua_file!")

	advert_config_get.init()
	--启动时就拉一次配置
	advert_common.timer_at(0, func_cmds.timer_work)
	--服务器每秒检测逻辑
	advert_common.timer_every(1, timer_check)
end

--===================================main function=====================================
--解析body
local function parse_body_data()
    local request_method = ngx.var.request_method
    if "POST" == request_method then
        ngx.req.read_body()
        local t = cjson.decode(ngx.req.get_body_data())

        if t == nil then
            t = table.loadstring(ngx.req.get_body_data()) --此时尝试用这种格式
        end

        log.debug("business_advert recv " .. ngx.req.get_body_data())
        if not t then
            local desc = "decode body failed."
            log.error(desc)
            return
        end
        -- 合并参数
        for k, v in pairs(t) do
            ngx.ctx.m_params[k] = v
        end
    end
end

--外部请求入口函数
FOO.enter = function()
	ngx.ctx.xff = biz_utils.real_client_ip() or "nil"
	ngx.ctx.m_params = ngx.req.get_uri_args()
	ngx.ctx.log = tonumber(ngx.ctx.m_params.log) or 0

	if not ns_auth_checker.ns_http_sec.decodeS7Url() then
		do return end
	end

	parse_body_data()
    ---------------------------------------------------------------------
    --请求参数打印 接口调试
	if ngx.ctx.m_params.urlinfo == '1' then
		log.debug( "=====================================" )
		ngx.req.read_body()
		log.debug( table.tostring(ngx.req.get_post_args()) )
		log.debug( table.tostring(ngx.req.get_headers()) )

		log.debug( ngx.ctx.xff .. "-" .. ngx.var.remote_addr .. ":" .. ngx.var.remote_port)
		log.debug( ngx.var.args )

		log.debug( ngx.var.request_uri )
		log.debug( ngx.var.uri )

		log.debug("worker_id= "..ngx.worker.id())
		log.debug( "=====================================" )
	end
    ---------------------------------------------------------------------

	--检测有效请求
	if ngx.ctx.m_params.act then
		local ret,reason = ns_auth_checker.not_first_request("act",ngx.ctx.m_params.time)
		if  not ret then
			return gg.return_table(reason)
		end
	end

	local action_     = false
	local commands_   = false
	local auth_       = false

    --外网客户端act
	if  ngx.ctx.m_params.act then
		action_      = ngx.ctx.m_params.act
		commands_    = func_acts
		auth_        = ngx.ctx.m_params.md5 or ngx.ctx.m_params.auth
    --内网命令cmd
	elseif ngx.ctx.m_params.cmd then
		action_      = ngx.ctx.m_params.cmd
		commands_    = func_cmds
		auth_        = ngx.ctx.m_params.auth or ngx.ctx.m_params.token
	else
		log.debug("warn::business_advert http request error, command not define")
		return
	end

	--检查必须的参数
	if  auth_ and ngx.ctx.m_params.uin and #ngx.ctx.m_params.uin > 0 and ngx.ctx.m_params.time then
		--从服务器内部调用的接口
		if ngx.ctx.m_params.cmd then
			if not ns_auth_checker.check_uin_safe( ngx.ctx.m_params.uin ) then
				return
			end
		--校验参数正确 检查md5
		else
			--if ns_auth_checker.checkMd5(auth_, ngx.ctx.m_params.time, ngx.ctx.m_params.uin) == false then
			if not ns_auth_checker.check_encrypt_by_ver() then
				log.day_list(ADVERT, "md5_error|" .. ngx.ctx.m_params.uin .. "|" .. action_  .. "|" .. (ngx.ctx.m_params.s2t or 'no_s2t') .. "|" .. 
				                (ngx.ctx.request_uri_s7 or 'nil') .. "|" .. (ngx.var.request_uri or 'nil') );
				return
			end
		end
	else
		--参数错误
		log.debug("params error no md5.")
		log.day_list(ADVERT, "no_md5|" .. (ngx.ctx.m_params.uin or 'nil') .. "|" .. (action_ or 'nil') ..
				"|" .. (ngx.ctx.m_params.s2t or 'no_s2t') ..
		                "|" .. (ngx.ctx.request_uri_s7 or 'nil') .. "|" .. (ngx.var.request_uri or 'nil') )
		return
	end

	log.debug( "action_ = "..action_)

	gg.init()

	--执行命令cmd
	if  commands_[ action_ ] then
		local uin_ =  ngx.ctx.m_params.uin or 0
		log.debug( "command=" .. action_  .. ", uin=" .. uin_);
		commands_[ action_ ]()
	else
        log.debug("business_advert http request error, the command is undefined ,command:" .. (action_ or "empty"))
	end

	gg.final()
end

return FOO